module key_debounce(
    input 	wire	clk,        // 时钟信号输入
    input 	wire 	rst_n,      // 复位信号，低电平有效
    input 	wire 	key,        // 按键输入

    output 	reg 	flag,       // 抖动标志，0表示抖动中，1表示抖动结束
    output 	reg	key_value  // 按键稳定后的值
);

// 定义参数MAX_NUM，用于设置消抖计数的最大值
parameter MAX_NUM = 20'd1_000_000;

// 内部信号声明
reg [19:0] delay_cnt;  // 用于消抖的计数器，足够大以覆盖抖动时间
reg key_reg;            // 上一次按键的状态

// 第一个always块：处理按键抖动
always @(posedge clk or negedge rst_n) begin
    if(!rst_n) begin
        key_reg <= 1;        // 复位时，将上一次按键状态设为高电平
        delay_cnt <= 0;      // 复位时，清零计数器
    end
    else begin
        key_reg <= key;      // 非复位时，更新上一次按键状态
        // 当上一次按键状态与当前按键状态不一致时，认为是抖动开始，重置计数器
        if(key_reg != key) begin
            delay_cnt <= MAX_NUM;
        end
        else begin
            // 如果按键状态一致，开始计数，直到计数器减到0
            if(delay_cnt > 0)
                delay_cnt <= delay_cnt - 1;
            else
                delay_cnt <= 0;
        end
    end
end

// 第二个always块：在按键稳定后输出按键值和标志
always @(posedge clk or negedge rst_n) begin
    if(!rst_n) begin
        flag <= 0;            // 复位时，抖动标志设为0
        key_value <= 1;       // 复位时，按键值设为高电平
    end
    else begin
        // 当计数器的值减到1时，认为按键已经稳定，更新抖动标志和按键值
        if(delay_cnt == 1) begin
            flag <= 1;
            key_value <= key;
        end
        else begin
            // 如果计数器还没减到1，保持抖动标志为0，按键值不变
            flag <= 0;
            key_value <= key_value;
        end
    end
end

endmodule